#include "rtx.h"
#include "rtx_inc.h"
#include "system_processes.h"
#include "debug.h"
#include "processes.h"

SINT32 register_kcd(CHAR command)
{
	MESSAGE *msg = NULL;
	msg = (MESSAGE *)request_memory_block();

	msg->message_type = CALL;
	msg->message_content[0] = command;
	msg->message_content[1] = '\0';

	return(send_message(KCD_PROCESS, msg));
}

VOID kcd_process (VOID)
{
	MESSAGE *msg = NULL;
	MESSAGE *new_msg = NULL;
	UINT32 mapped_commands[128];
	UINT32 counter = 0;
	BOOLEAN buffer = FALSE;
	UINT32 i;

	while(1)
	{
		int sender = 0;
		msg = (MESSAGE *)receive_message(&sender);

		if(msg->message_type == CALL)
		{
			mapped_commands[msg->message_content[0]] = sender;
		}
		else if(msg->message_type == INPUT)
		{
			if(msg->message_content[0] == '%' && !buffer)
			{
				new_msg = (MESSAGE*)request_memory_block();
				buffer = TRUE;
			}
			else if(buffer)
			{
				if(msg->message_content[0] == CR)
				{
					counter = 0;
					send_message(mapped_commands[new_msg->message_content[0]], new_msg);
					buffer = FALSE;
				}
				else
				{
					new_msg->message_content[counter] = msg->message_content[0];
					counter++;
				}
			}
			else if(msg->message_content[0] == '!' && !buffer)
			{
				// Our debug statement to print all PCB and their current priorities

				debug_out_string("PID\tPriority\n\r");

				for( i = 0; i < NUM_PROCESSES ; i++ )
				{
					debug_out_int(pcbs[i].process_ID);
					debug_out_string("\t");
					debug_out_int(pcbs[i].priority);
					debug_out_string("\n\r");
				}
			}
			else if(msg->message_content[0] == '~' && !buffer)
			{
				// Our debug statement to print all PCB and their current priorities and their current state

				debug_out_string("PID\tPriority\tState\n\r");

				for( i = 0; i < NUM_PROCESSES ; i++ )
				{
					debug_out_int(pcbs[i].process_ID);
					debug_out_string("\t");
					debug_out_int(pcbs[i].priority);
					debug_out_string("\t");
					debug_out_int(pcbs[i].process_state);
					debug_out_string("\n\r");
				}
			}
			else if(msg->message_content[0] == '@' && !buffer)
			{
				// Our debug statement to print the number of available memory blocks
				debug_out_string("Available Memory: ");
				debug_out_int(avail_mem);
				debug_out_string("\n\r");
			}
		}

		msg->message_type = DISPLAY_TEXT;
		send_message(CRT_PROCESS, msg);
		release_processor();
	}
}

VOID crt_process (VOID)
{
	MESSAGE *msg = NULL, *output = NULL;
	UINT32 i = 0;

	while(1)
	{
		int sender = 0;
		msg = (MESSAGE *)receive_message(&sender);

		if(msg != NULL)
		{
			if(msg->message_type == DISPLAY_TEXT)
			{
				i = 0;
				while(msg->message_content[i] != '\0')
				{
					output = (MESSAGE *)request_memory_block ();
                    output->message_content[0] = msg->message_content[i];
                    send_message (UART_I_PROCESS, output);
                    //SERIAL1_IMR = 3;
					i++;
				}
			}
		}
		release_memory_block(msg);
		release_processor();
	}
}

